<!--
 * @description: 剧本章节
 * @fileName: ScriptChapter
 * @author: 17076
 * @date: 2025/3/20-下午5:20
 * @version: V1.0.0
-->

<template>
  <div class="chapter-content">
    <el-row :gutter="10">
      <el-col :md="8" :sm="8" :lg="7" :xs="8" :xl="5">
        <div class="card screen-left">
          <div class="form-content" :style="{ height: $baseTableHeight(-20) + 'px' }">
            <el-form ref="form" :model="uploadForm" :rules="rules" label-width="120px" label-position="top">
              <el-form-item label="剧本上传" prop="fileId">
                <template slot="label">
                  <span>
                    剧本上传
                    <el-tooltip trigger="click" placement="bottom-start" popper-class="tips-popper">
                      <template #content>
                        <div class="tips-content">
                          <div class="flex-row tips-header">
                            <i class="el-icon-warning-outline" />
                            <span>您可以参考示例的格式来上传文件，要是觉得复杂，直接提交剧本内容也没问题，期待您的精彩创作</span>
                          </div>
                          <div class="flex-column tips-body">
                            <div class="main-title">故事大纲</div>
                            <div class="content-title">边关遭外族侵袭，猎户之女扶摇家破人亡。她凭借祖传玄铁令集结义士，从懵懂少女成长为抗敌领袖，在与外族的殊死搏斗中，以热血守护家园。</div>
                            <div class="main-title">剧情梗概</div>
                            <div class="content-title">外族铁骑踏碎边境小镇，扶摇父亲遇害。她获玄铁令号令江湖，逃亡时结识隐世高手萧砚等。众人以玄铁令为盟，利用地形设伏，重创外族，扶摇也成为敌人眼中钉。</div>
                            <div class="main-title">主要人物</div>
                            <div class="content-title">
                              <p>扶摇：坚毅果敢的猎户女，抗敌领袖。</p>
                              <p>萧砚：武艺高强的隐世高手，扶摇助力。</p>
                              <p>阿依娜：外族异见者，传递情报。</p>
                              <p>乌图：凶残的外族将领，视扶摇为死敌。</p>
                            </div>
                            <div class="main-title">剧本</div>
                            <div class="content-title">
                              <p style="color: #FFFFFF">第一集：战火燃眉</p>
                              <p><span style="color: #FFFFFF">场 1：</span>热闹集市上，扶摇背着猎物与商贩说笑。突然，外族骑兵挥刀闯入，百姓惊慌逃窜。扶摇父亲为保护她，被骑兵砍倒。扶摇哭喊着扑向父亲：“爹！” 骑在马上的乌图满脸凶相：“这片土地，从此归我们！”</p>
                              <p><span style="color: #FFFFFF">场 2：</span>傍晚，扶摇家中，她抱着父亲遗体痛哭。在整理遗物时，发现一枚刻着神秘纹路的玄铁令。屋外传来脚步声，扶摇迅速藏起玄铁令，抄起猎刀警惕起来。萧砚缓缓走进，举起双手：“别怕，我也是来对抗他们的。”</p>
                            </div>
                            <div class="content-title">
                              <p style="color: #FFFFFF">第二集：初战告捷</p>
                              <p><span style="color: #FFFFFF">场 1：</span>三日后，密林深处营地，扶摇与萧砚召集数十名义士商议作战计划。阿依娜悄悄潜入，带来外族粮草运输路线的情报。扶摇眼神坚定：“我们在峡谷设伏，劫了他们的粮草！” 另一边，得知消息的乌图怒拍桌子：“小小蝼蚁，也敢坏我大事！”</p>
                              <p><span style="color: #FFFFFF">场 2：</span>：深夜，峡谷中，月光下扶摇等人埋伏在两侧。当外族粮草车队进入，滚石、利箭倾泻而下。乌图率骑兵赶来支援，却陷入义军的火攻陷阱。扶摇挥舞长刀大喊：“为乡亲们报仇！” 乌图狼狈撤退，咬牙切齿：“扶摇，我不会放过你！”</p>
                            </div>
                          </div>
                        </div>
                      </template>
                      <i class="tips">Tips</i>
                    </el-tooltip>
                  </span>
                </template>
<!--                <div v-if="$route.query.id">-->
<!--                  <i class="el-icon-document" />-->
<!--                  <span style="margin-left: 10px">{{ uploadForm['playName'] }}</span>-->
<!--                </div>-->
                <el-upload
                  class="upload-demo"
                  :action="uploadOption.action"
                  :headers="uploadOption.headers"
                  :on-remove="handleRemove"
                  :on-success="handleSuccess"
                  :multiple="false"
                  drag
                  accept=".doc,.docx,.txt,.pdf"
                  :file-list="fileList"
                  :show-file-list="false"
                >
                  <svg-icon v-if="playName" :icon-class="formatterFileType(playName)"/>
                  <svg-icon v-else icon-class="file_upload"/>
                  <div v-if="playName" :title="playName" class="file-name etc">{{ playName }}</div>
                  <div v-else class="el-upload__tip">请上传doc，txt，pdf文件，大小在60M以内</div>
                  <span class="upload-button">{{ playName ? '重新选择' : '选择文件' }}</span>
                </el-upload>
              </el-form-item>
              <el-form-item label="拆分规则" prop="splitType">
                <el-radio-group v-model="uploadForm['splitType']">
                  <el-row :gutter="10">
                    <el-col
                      v-for="item in splitRuleList"
                      :key="item.code"
                      :span="12"
                      style="margin-bottom: 10px"
                    >
                      <el-radio
                        :label="item.code"
                        border
                      >
                        {{ item.name }}
                      </el-radio>
                    </el-col>
                  </el-row>
                </el-radio-group>
              </el-form-item>
              <el-form-item v-if="uploadForm.splitType === '3'" prop="splitTextNum">
                <el-input
                  v-model="uploadForm['splitTextNum']"
                  placeholder="输入字数限制"
                  clearable
                />
              </el-form-item>
              <!--              <el-form-item label="画面比例" prop="pictureScale">-->
              <!--                <el-row :gutter="10">-->
              <!--                  <el-col-->
              <!--                    v-for="item in pictureScaleList"-->
              <!--                    :key="item.code"-->
              <!--                    :span="6"-->
              <!--                    style="margin-bottom: 10px"-->
              <!--                    @click.native="handlePictureScale(item)"-->
              <!--                  >-->
              <!--                    <div :class="['flex-column', 'flex-center', 'picture-scale-item', uploadForm['pictureScale'] === item.code ? 'active' : '']">-->
              <!--                      <div class="max-box">-->
              <!--                        <div class="picture-scale-tag" :data-ratio="item.code" />-->
              <!--                      </div>-->
              <!--                      <span>{{ item.name }}</span>-->
              <!--                    </div>-->
              <!--                  </el-col>-->
              <!--                </el-row>-->
              <!--              </el-form-item>-->
            </el-form>
          </div>
          <el-button class="liner-button generate-button" :loading="isLoading" @click="handleCreate">{{ uploadForm['id'] ? '重新生成' : '开始创作' }}</el-button>
        </div>
      </el-col>
      <el-col :md="16" :sm="16" :lg="17" :xs="16" :xl="19">
        <div class="card screen-right" :style="{ height: $baseTableHeight(-100) + 'px' }">
          <!--          <el-alert-->
          <!--            title="可修改输入框内容，按回车键在光标处拆分新分镜，点击右边箭头向上合并分镜。"-->
          <!--            type="info"-->
          <!--            show-icon>-->
          <!--          </el-alert>-->
          <!--          <div
            v-for="item in playContent['playParts']"
            :key="item.id"
            class="flex-row part-item"
            :style="{ height: playContent.splitType === '3'? '500px' : '40px' }"
          >-->
          <span v-if="Object.keys(playContent).length > 0 && !isLoading" style="color: #5C6872;font-size: 12px">光标定位后按<span style="color: #FFFFFF">【Enter】</span>键可快速分镜，点击内容右侧<span style="color: #FFFFFF">【合并】</span>图标可快速上下合并分镜，</span>
          <div v-if="playContent['storyLine']" class="part" style="margin-top: 10px">
            <div class="flex-row" style="align-items: center; justify-content: space-between" @click="() => { isExpand1 = !isExpand1 }">
              <span>故事大纲</span>
              <span style="color: #5C6872;cursor: pointer">{{ isExpand1 ? '收起' : '展开' }}<i :class="isExpand1 ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" /></span>
            </div>
            <div :class="[ isExpand1 ? '' : 'part-etc' ]">{{ playContent['storyLine'] }}</div>
          </div>
          <div v-if="playContent['synopsis']" class="part">
            <div class="flex-row" style="align-items: center; justify-content: space-between" @click="() => { isExpand2 = !isExpand2 }">
              <span>剧情梗概</span>
              <span style="color: #5C6872;cursor: pointer">{{ isExpand2 ? '收起' : '展开' }}<i :class="isExpand2 ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" /></span>
            </div>
            <div :class="[ isExpand2 ? '' : 'part-etc' ]">{{ playContent['synopsis'] }}</div>
          </div>
          <template v-if="!isLoading">
            <div
              v-for="item in playContent['playParts']"
              :key="item.id"
              class="flex-row part-item"
            >
              <span class="seq">{{ `${item['chapterNum']}-${item['partIndex']}` }}</span>
              <el-input
                :id="`part${item.id}`"
                v-model="item['partInfo']"
                type="textarea"
                autosize
                class="part-content"
                @keydown.native="handleKeyChange($event, item)"
              />
              <!--            &lt;!&ndash;此版不做字数限制拆分器的判断&ndash;&gt;-->
              <!--            <el-input-->
              <!--              v-model="item['partInfo']"-->
              <!--              class="part-content"-->
              <!--              @keyup.enter.native="handleKeyChange($event, item)"-->
              <!--            />-->
              <!--            <el-tooltip v-if="uploadForm.splitType !== '3'" content="向上合并" placement="left">
                <div class="part-combine" @click="handleCombine(item)" />
              </el-tooltip>-->
              <i class="el-icon-delete delete-button" @click="handleDeletePart(item)" />
              <el-tooltip v-if="Number(playStatus) < 3" content="向上合并" placement="left">
                <div class="part-combine" @click="handleCombine(item)" />
              </el-tooltip>
            </div>
          </template>
          <el-empty v-if="Object.keys(playContent).length === 0 && !isLoading" description="暂无章节内容" :style="{ height: $baseTableHeight(-60) + 'px' }">
            <template slot="image">
              <img src="@/assets/common/empty.png"/>
            </template>
          </el-empty>
          <img v-if="isLoading" src="~@/assets/write/loading.gif" class="loading">
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { baseURL } from '@/config/net.config'
import { commonDownloadFile, commonUploadFile, deleteFile } from '@/api/config/uploadApi'
import { splitPlay, combinePart, divisionPart, deletePart } from '@/api/play'
import { mapGetters, mapActions } from 'vuex'

export default {
  name: 'ScriptChapter',
  props: {
    lastPlayInfo: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    const validatorNum = (rule, value, callback) => {
      if (this.uploadForm.splitType === '3') {
        if (value) {
          if (value < 100) {
            callback(new Error('字数限制不能小于100'))
          } else if (!/^\d+$/.test(value)) {
            callback(new Error('字数限制必须为数字'))
          } else {
            callback()
          }
        } else {
          callback(new Error('字数限制不能为空'))
        }
      } else {
        callback()
      }
    }
    return {
      uploadForm: {
        splitType: '2',
        pictureScale: '2'
      },
      rules: {
        fileId: [
          { required: true, message: '请上传剧本', trigger: 'blur' }
        ],
        splitType: [
          { required: true, message: '请选择拆分规则', trigger: 'blur' }
        ],
        splitTextNum: [
          { required: true, validator: validatorNum, trigger: 'blur' }
        ],
        pictureScale: [
          { required: true, message: '请选择画面比例', trigger: 'blur' }
        ]
      },
      // 是否展开
      isExpand1: false,
      isExpand2: false,
      // 文件上传配置
      uploadOption: {
        action: baseURL + commonUploadFile,
        headers: {
          'Auth-Token': localStorage.getItem('MyToken')
        }
      },
      // 剧本文件名称
      playName: null,
      // 文件下载地址
      downloadUrl: baseURL + commonDownloadFile,
      // 拆分规则
      splitRuleList: JSON.parse(sessionStorage.getItem('splitType')),
      // 画面比例
      pictureScaleList: JSON.parse(sessionStorage.getItem('pictureScale')),
      // 上传的剧本内容
      playContent: {},
      fileList: [],
      // 剧本信息
      playInfo: {},
      // 是否正在生成
      isLoading: false
    }
  },
  computed: {
    // 剧本状态
    ...mapGetters({
      playStatus: 'lens/playStatus',
      cachePlayInfo: 'play/cachePlayInfo'
    })
  },
  watch: {
    lastPlayInfo: {
      handler(val) {
        if (this.$baseLodash.isEmpty(val)) return
        this.uploadForm = Object.assign({ splitType: '2' }, val)
        this.playContent = val
        this.changeShowNext1(true)
        // 文件名称保存
        this.playName = val['fileName']
      },
      immediate: true
    }
  },
  mounted() {
    console.log(this.cachePlayInfo, 89898989)
    // 如果剧本信息存在，直接赋值
    if (!this.$baseLodash.isEmpty(this.cachePlayInfo)) {
      this.uploadForm = Object.assign({ splitType: '2' }, this.cachePlayInfo)
      this.playContent = this.cachePlayInfo
      this.changeShowNext1(true)
      // 文件名称保存
      this.playName = this.cachePlayInfo['fileName']
    }
  },
  methods: {
    ...mapActions({
      changeShowNext1: 'lens/changeShowNext1',
      changePlayInfo: 'play/changePlayInfo'
    }),
    // 获取分段
    // 画面比例切换
    handlePictureScale(item) {
      this.$set(this.uploadForm, 'pictureScale', item.code)
    },
    // 文件类型
    formatterFileType(playName) {
      if (!playName) return
      const fileExtension = playName.split('.').pop().toLowerCase()
      console.log(fileExtension, 7878)
      switch (fileExtension) {
        case 'doc':
          return 'doc'
        case 'docx':
          return 'doc'
        case 'txt':
          return 'txt'
        case 'pdf':
          return 'pdf'
        default:
          return 'file'
      }
    },
    // 文件删除
    handleRemove() {
      deleteFile(this.uploadForm['fileId']).then(res => {
        this.$set(this.uploadForm, 'fileId', '')
      })
    },
    // 上传成功
    handleSuccess(res, file) {
      if (res.code === 200) {
        this.$set(this.uploadForm, 'fileId', res.data.id)
        // 保存文件名称
        this.playName = file.name
      }
    },
    // 删除分段
    handleDeletePart(item) {
      this.$baseConfirm('确定删除该分段吗?', '提示', async() => {
        const res = await deletePart({ id: item['id'] })
        if (res['code'] === 200) {
          this.playContent['playParts'] = res.data
        } else {
          this.$baseMessage.error(res['msg'] || '删除失败!')
        }
      })
    },
    // 监听按键
    handleKeyChange(e, item) {
      // 监听回车键拆分
      if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey) {
        const input = e.target
        const cursorPosition = input.selectionStart // 获取光标位置
        const textBeforeCursor = item['partInfo'].substring(0, cursorPosition) // 光标前的字符串
        const textAfterCursor = item['partInfo'].substring(cursorPosition) // 光标后的字符串
        divisionPart({ id: item.id, text1: textBeforeCursor, text2: textAfterCursor }).then(res => {
          if (res['code'] === 200) {
            this.playContent['playParts'] = res.data
          }
        })
        e.preventDefault()
      }
    },
    // 向上合并
    async handleCombine(item) {
      // 当前条目的id
      const currentId = item.id
      // 找到当前条目的索引
      const currentIndex = this.playContent['playParts'].findIndex(part => part.id === currentId)
      // 找到上一个条目的索引
      const prevIndex = currentIndex - 1
      // 获取上一个条目id
      const lastId = this.playContent['playParts'][prevIndex]['id']
      const res = await combinePart({ id1: lastId, id2: currentId })
      if (res['code'] === 200) {
        this.playContent['playParts'] = res.data
      } else {
        this.$baseMessage.error(res['msg'] || '合并失败!')
      }
    },
    // 智能生成
    handleCreate() {
      if (Number(this.playStatus > 2)) {
        this.$baseMessage.error('该剧本已进入分镜内容拆分状态，无法再次生成!')
        return
      }
      if (this.uploadForm.splitType === '4') {
        this.$baseMessage.error('该功能暂未开放!')
        return
      }
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.isLoading = true
          splitPlay({ ...this.uploadForm, descType: '3' }).then(res => {
            this.isLoading = false
            this.playContent = { ...res.data['play'], playParts: res.data['playParts'] }
            this.uploadForm = res.data['play']
            this.changeShowNext1(true)
            this.$emit('savePlay', this.uploadForm['id'])
            // 保存剧本信息
            this.changePlayInfo(this.playContent)
          }).catch(() => {
            this.isLoading = false
          })
        }
      })
    }
  }
}
</script>

<style scoped lang="scss">
.chapter-content {
  margin-top: 10px;
  color: #FFFFFF;
  .card {
    background: $base-content-background;
    padding: 20px 10px;
    box-sizing: border-box;
    border-radius: 8px;
  }
  .picture-scale-item {
    width: 100%;
    padding: 12px 10px;
    box-sizing: border-box;
    border-radius: 5px;
    background: #272C36;
    border: 1px solid #39414E;
    color: #686B7A;
    cursor: pointer;
    &.active {
      border-color: #FFFFFF;
      color: #FFFFFF;
      .max-box .picture-scale-tag {
        background: #B6C7D1;
      }
    }
    .max-box {
      width: 100%;
      height: 20px;
      .picture-scale-tag {
        background: #686B7A;
        border-radius: 2px;
        margin: 0 auto;
        max-width: 100%;
        max-height: 100%;
        aspect-ratio: $base-aspect-ratio-1;
        &[data-ratio="2"] {
          aspect-ratio: $base-aspect-ratio-2;
        }
        &[data-ratio="3"] {
          aspect-ratio: $base-aspect-ratio-3;
        }
        &[data-ratio="4"] {
          aspect-ratio: $base-aspect-ratio-4;
        }
        &[data-ratio="5"] {
          aspect-ratio: $base-aspect-ratio-5;
        }
        &[data-ratio="6"] {
          aspect-ratio: $base-aspect-ratio-6;
        }
        &[data-ratio="7"] {
          aspect-ratio: $base-aspect-ratio-7;
        }
        &[data-ratio="8"] {
          aspect-ratio: $base-aspect-ratio-8;
        }
      }
    }
  }
  .screen-left {
    //position: relative;
    .form-content {
      overflow: auto;
      padding: 0 10px;
      .tips {
        font-size: 12px;
        color: #5C6872;
        margin-left: 8px;
        font-style: normal;
        &:hover {
          color: $base-color-default;
        }
      }
      .upload-demo {
        width: 100%;
        ::v-deep {
          .el-upload {
            width: 100%;
          }
          .el-upload-dragger {
            background: #272C36 !important;
            border-color: #5C6872;
            width: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            color: #B6C7D1;
            padding: 0 10px;
            box-sizing: border-box;
            overflow: hidden;
            height: 160px;
            .svg-icon {
              width: 40px;
              height: 40px;
            }
            .file-name {
              font-size: 12px;
              max-width: 100%;
              color: #FFFFFF;
            }
            .upload-button {
              border: 1px solid #B6C7D1;
              border-radius: 5px;
              padding: 5px 10px;
              font-size: 12px;
              line-height: normal;
              margin-top: 10px;
            }
          }
        }
      }
      //margin-bottom: 80px;
    }
    .generate-button {
      margin-top: 10px;
      width: calc(100% - 20px);
    }
    .style-item {
      align-items: center;
      cursor: pointer;
      margin-bottom: 10px;
      .el-image {
        width: 100%;
        height: 100px;
        border-radius: 8px;
        border: 1px solid $base-content-background;
      }
      span {
        margin-top: 10px;
        font-size: 12px;
      }
      &-active {
        .el-image {
          border: 1px solid $base-color-default;
        }
        span {
          color: $base-color-default;
        }
      }
    }
  }
  .screen-right {
    position: relative;
    overflow: auto;
    padding: 10px;
    box-sizing: border-box;
    .part {
      padding: 10px;
      border: 1px solid #39414E;
      background: #272C36;
      border-radius: 8px;
      margin-bottom: 10px;
      margin-right: 50px;
      >div:nth-child(2) {
        margin-top: 10px;
        line-height: 20px;
      }
      &-etc {
        display: -webkit-box;
        -webkit-line-clamp: 4;
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
    .part-item {
      align-items: center;
      margin-bottom: 10px;
      position: relative;
      border: 1px solid #39414E;
      background: #272C36;
      border-radius: 8px;
      margin-right: 50px;
      cursor: pointer;
      padding-right: 10px;
      &.active {
        border-color: $base-color-default;
      }
      &:hover {
        border-color: $base-color-default;
        .delete-button {
          display: block;
        }
      }
      .seq {
        color: rgba(255,255,255,.5);
        width: 40px;
        text-align: center;
      }
      .delete-button {
        position: absolute;
        right: 8px;
        cursor: pointer;
        display: none;
      }
      .part-combine {
        position: absolute;
        right: -50px;
        top: -44px;
        width: 48px;
        height: 76px;
        background: url("~@/assets/write/paragraph-combine.png") no-repeat;
        background-size: 100% 100%;
        cursor: pointer;
        display: none;
      }
      &:nth-child(2) {
        margin-top: 10px;
      }
      .part-content {
        border-left: 1px solid #39414E;
        min-height: 44px;  /* 初始最小高度 */
        overflow-y: hidden; /* 隐藏滚动条 */
        resize: none;
        //height: 100%;
        //line-height: 100%;
        width: calc(100% - 40px);
        ::v-deep {
          .el-input__inner {
            height: 100%;
          }
          .el-textarea__inner {
            min-height: 44px !important;
            line-height: 22px;
            resize: none;
            border: none;
            border-radius: 8px;
          }
        }
      }
      &:nth-child(n+3):hover {
        .part-combine {
          display: block;
        }
      }
    }
    .loading {
      width: 60px;
      height: 60px;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    pre {
      background: #272C36;
      border: 1px solid #39414E;
      padding: 10px;
      box-sizing: border-box;
      border-radius: 8px;
      margin-bottom: 10px;
      font-size: 14px;
      white-space: pre-wrap;
      word-break: break-all;
    }
    .basic-attribute {
      //background: #272C36;
      //border: 1px solid #39414E;
      //padding: 10px;
      //border-radius: 8px;
      margin: 10px 0;
      margin-right: 80px;
      line-height: 22px;
    }
  }
}
::v-deep {
  .el-radio {
    width: 100%;
    border: 1px solid transparent;
    background: #272C36;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    padding: 25px 10px;
    border-radius: 8px;
  }
  .el-radio.is-bordered.is-disabled {
    border-color: transparent;
  }
  .extra-form {
    margin-bottom: 0 !important;
  }

}
</style>
